#include <iostream>
#include <string>
#include <ctime>
#include <sys/types.h>
#include <unistd.h>
#include <memory.h>

#include "Socket.hpp"
#include "Protocol.hpp"

int main(int argc, char *argv[])
{
  if (argc != 3)
  {
    std::cout << argv[0] << " :serverip serverport";
    return 0;
  }

  std::string serverip = argv[1];
  uint16_t serverport = std::stoi(argv[2]);

  Net_Work::Socket *conn = new Net_Work::TcpSocket();
  if (!conn->BuildConnectSocketMethod(serverip, serverport))
  {
    std::cerr << "connect " << serverip << ":" << serverport << " fail" << std::endl;
  }
  std::cout << "connect " << serverip << ":" << serverport << " success!" << std::endl;
  std::unique_ptr<Protocol::Factory> factory(new Protocol::Factory());

  srand(time(nullptr) ^ getpid());
  std::string oper = "+-*/%^=&";
  while (true)
  {
    // 构建请求
    int x = rand() % 100;
    usleep(rand() % 1234);
    int y = rand() % 100;
    usleep((rand() % 1234));
    char op = oper[rand() % oper.size()];
    std::shared_ptr<Protocol::Request> req = factory->BuildRequest(x, y, op);

    // 序列化
    std::string requeststr;
    req->Serialize(&requeststr);

    std::string teststr = requeststr + " = ";

    // 添加报头
    requeststr = Protocol::Encode(requeststr); // 没问题的
    // 发送
    conn->Send(requeststr);

    // 接收响应
    std::string responsestr;
    while (true)
    {
      if (!conn->Recv(&responsestr, 1024))
      {
        std::cout << "Recv Error" << std::endl;
        break;
      }
      std::string response;
      // 解包
      if (!Protocol::Decode(responsestr, &response))
      {
        std::cout << "Decode Error" << std::endl;
        continue;
      }

      // 反序列化
      auto resp = factory->BuildResponse();
      resp->DeSerialize(response);

      // 显示
      std::cout << teststr << resp->Getresult() << "[" << resp->Getcode() << "]" << std::endl;
      break;
    }
    sleep(1);
  }
  std::cout << "CloseSockfd" << std::endl;
  conn->CloseSockfd();
  return 0;
}
